#ifndef __TcpConnection_H__
#define __TcpConnection_H__

#include "EventLoop.hpp"
#include "Noncopyable.hpp"
#include "Socket.hpp"
#include "SocketIO.hpp"
#include "InetAddress.hpp"

#include <functional>
#include <memory>

namespace wd
{
class TcpConnection;
using TcpConnectionPtr=std::shared_ptr<TcpConnection>;
using TcpConnectionCallback=std::function<void(TcpConnectionPtr)>;


class TcpConnection
: Noncopyable
, public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(int fd);

    void send(const string & msg);
    string receive();
    string toString() const;
    bool isClosed() const;

    void shutdown();

    //函数的参数不能使用右值引用表达移动语义，
    //这样会将EventLoop类中的三个函数对象转移走
    //会造成只有第一个TcpConnection对象拥有三个函数对象
    //接下来的连接都无法正常使用三个函数对象
    //所以参数形式必须改成const &
    void setAllCallbacks(const TcpConnectionCallback & cb1,
                         const TcpConnectionCallback & cb2,
                         const TcpConnectionCallback & cb3)
    {
        _onConnection = cb1;
        _onMessage = cb2;
        _onClose = cb3;
    }

    //针对于三个函数对象的调用
    void handleNewConnectionCallback();
    void handleMessageCallback();
    void handleCloseCallback();

private:
    InetAddress getLocalAddress() const;
    InetAddress getPeerAddress() const;

private:
    Socket _sock;
    SocketIO _socketIO;
    InetAddress _localAddr;
    InetAddress _peerAddr;

    TcpConnectionCallback _onConnection;
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;
};

}//end of namespace wd


#endif

